package jp.syuriken.snsw.terenaibot.internal;

import java.util.MissingResourceException;
import java.util.logging.Level;

import jp.syuriken.snsw.terenaibot.BotConfiguration;
import jp.syuriken.snsw.terenaibot.ConfigurationException;
import jp.syuriken.snsw.terenaibot.ConfigurationExceptionType;
import jp.syuriken.snsw.terenaibot.NullPost;
import jp.syuriken.snsw.terenaibot.Post;
import jp.syuriken.snsw.terenaibot.PostWrapper;
import jp.syuriken.snsw.terenaibot.WrapperException;
import jp.syuriken.snsw.utils.MyResourceBundle;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationBuilder;

/**
 * ツイッター用のポストラッパ。直接的な使用は避けるべきです。
 * 
 * @author $Author: snswinhaiku.lo@gmail.com $
 */
public class TwitterPostWrapper extends PostWrapper {
	
	/** Service Temporarily Unavailableのステータスコード */
	private static final int STATUS_CODE_TEMPORARIRY_UNAVAILABLE = 503;
	
	private Twitter twitter;
	

	/**
	 * インスタンスを生成する。
	 * @param conf 設定
	 * @param twitter Twitterインスタンス
	 */
	public TwitterPostWrapper(BotConfiguration conf, Twitter twitter) {
		super();
		this.twitter = twitter;
	}
	
	@Override
	public Post getPost(String postId) {
		try {
			return new TwitterPost(twitter.showStatus(Long.parseLong(postId)));
		} catch (NumberFormatException e) {
			throw e;
		} catch (TwitterException e) {
			return NullPost.getInstance();
		}
	}
	
	@Override
	public Object getPostActionClass() {
		return twitter;
	}
	
	private String getStringFromConfiguration(MyResourceBundle resourceBundle, String configName)
			throws ConfigurationException {
		try {
			return resourceBundle.getString(configName);
		} catch (MissingResourceException e) {
			throw new ConfigurationException(botConfiguration.getConfigurationFile(), configName,
					ConfigurationExceptionType.NOT_FOUND);
		}
	}
	
	@Override
	public String getUserName() throws IllegalStateException, WrapperException {
		return getUserName(true);
	}
	
	private String getUserName(boolean isFirstAction) throws IllegalStateException, TwitterWrapperException {
		try {
			return twitter.getScreenName();
		} catch (IllegalStateException e) {
			throw e;
		} catch (TwitterException e) {
			int statusCode = e.getStatusCode();
			if (isFirstAction && statusCode == STATUS_CODE_TEMPORARIRY_UNAVAILABLE) {
				botConfiguration.getLogger().log(Level.INFO,
						"Twitter returned status-code" + statusCode + " while getUserName(); retrying...");
				return getUserName(false);
			} else {
				throw new TwitterWrapperException(e);
			}
		}
	}
	
	@Override
	public String getWrapperName() {
		return "TwitterPostWrapper";
	}
	
	@Override
	public TwitterPostWrapper init(BotConfiguration configuration) throws ConfigurationException {
		MyResourceBundle resourceBundle;
		resourceBundle = configuration.getResourceBundle();
		
		ConfigurationBuilder cb = new ConfigurationBuilder();
		cb.setDebugEnabled(true).setOAuthConsumerKey(getStringFromConfiguration(resourceBundle, "oauth.consumer_key"))
			.setOAuthConsumerSecret(getStringFromConfiguration(resourceBundle, "oauth.consumer_secret_key"))
			.setOAuthAccessToken(getStringFromConfiguration(resourceBundle, "oauth.access_token"))
			.setOAuthAccessTokenSecret(getStringFromConfiguration(resourceBundle, "oauth.access_token_secret"));
		TwitterFactory tf = new TwitterFactory(cb.build());
		twitter = tf.getInstance();
		return this;
	}
	
	@Override
	public Post post(String poststr) {
		super.post(poststr);
		return post(poststr, true);
	}
	
	private Post post(String poststr, boolean isFirstAction) {
		Status updateStatus;
		try {
			updateStatus = twitter.updateStatus(poststr);
		} catch (TwitterException e) {
			if (isFirstAction && e.getStatusCode() == STATUS_CODE_TEMPORARIRY_UNAVAILABLE) {
				return post(poststr, false);
			} else {
				botConfiguration.getLogger().log(Level.INFO, e);
				return NullPost.getInstance();
			}
		}
		TwitterPost post = new TwitterPost(updateStatus);
		return post;
	}
}
